#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "esp_timer.h"
#include "esp_log.h"
#include "esp_sleep.h"
#include "sdkconfig.h"

#define PERIODIC_US     1000000

static const char* TAG = "esp_timer";

// 单次触发定时器 句柄
esp_timer_handle_t oneshot_timer;
// 自动重载定时器 句柄
esp_timer_handle_t periodic_timer;

// 单次触发定时器 回调函数
static void oneshot_timer_callback(void* arg)
{
    // 获取从开机到现在的时间(us)
    int64_t time_since_boot = esp_timer_get_time();
    ESP_LOGI(TAG, "One-shot timer called, time since boot: %lld us", time_since_boot);
}

// 自动重载定时器 回调函数
static void periodic_timer_callback(void* arg)
{
    // 获取回调函数的参数 超时时间
    int timeout = (int) arg;
    // 获取从开机到现在的时间(us)
    int64_t time_since_boot = esp_timer_get_time();
    ESP_LOGI(TAG, "Periodic timer called, time since boot: %lld us", time_since_boot);
    if(time_since_boot>timeout){
        // 超时时间到，停止自动重载定时器
        ESP_LOGI(TAG, "Periodic timer timeout=%d, timer stop", timeout);
        // 停止自动重载定时器
        esp_timer_stop(periodic_timer);
        // 删除自动重载定时器
        esp_timer_delete(periodic_timer);
    }
}

void app_main(void)
{
    // 单次触发定时器 配置参数
    const esp_timer_create_args_t oneshot_timer_args = {
        // 定时器的回调函数
        .callback = &oneshot_timer_callback,
        // 定时器名称 方便debug
        .name = "one-shot"
    };
    // 创建 单次触发定时器
    esp_timer_create(&oneshot_timer_args, &oneshot_timer);
    // 单次启动 单次触发定时器, 6000000us后启动
    esp_timer_start_once(oneshot_timer, 6000000);
    ESP_LOGI(TAG, "Started one-shot timers, time since boot: %lld us", esp_timer_get_time());

    // 自动重载定时器 超时时间
    int timeout = 5*PERIODIC_US+esp_timer_get_time();
    // 自动重载定时器 配置参数
    const esp_timer_create_args_t periodic_timer_args = {
        // 定时器的回调函数
        .callback = &periodic_timer_callback,
        // 定时器的回调函数的参数
        .arg = (void*) timeout,
        // 定时器名称 方便debug
        .name = "periodic"
    };
    // 创建 自动重载定时器
    esp_timer_create(&periodic_timer_args, &periodic_timer);
    // 周期启动 自动重载定时器, 周期时间PERIODIC_US
    esp_timer_start_periodic(periodic_timer, PERIODIC_US);
}